﻿using Inovout.Kuajing.Models;
using Inovout.Kuajing.Repositories;
using Inovout.Models;
using Inovout.Services;
using NHibernate.Criterion;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Inovout.Kuajing.Services
{
    public class ShipmentOrderService : RepositoryService<ShipmentOrder>
    {
        protected ShipmentOrderRepository ShipmentOrderRepository
        {
            get { return (ShipmentOrderRepository)base.Repository; }
        }
        public override ShipmentOrder FindById(object id)
        {
            var order = base.FindById(id);
            base.Repository.Evict(order);
            return base.FindById(id);
        }
        private WangCangStoreService wangCangStoreService;
        private CommodityService commodityService;
        public ShipmentOrderService()
        {
            wangCangStoreService = new WangCangStoreService();
            commodityService = ComponentRegistry.Resolve<CommodityService>();
        }
        private object noObject = new object();
        public override void Create(ShipmentOrder entity)
        {
            lock (noObject)
            {
                Random ro = new Random();
                entity.No = "S" + DateTime.Now.ToString("yyyyMMddHHmmssfff") + ro.Next(10, 99).ToString();
            }
            entity.Status = ShipmentOrderStatus.Paid;
            entity.ExternalShipperId = entity.Items.First().Commodity.ExternalShipperId;

            base.Create(entity);

                foreach (var item in entity.Items)
                {
                    item.Commodity.Stock--;
                    commodityService.Save(item.Commodity);
                }
  
        }

        public ShipmentOrder GetByNo(string no)
        {
            return base.Repository.Query().Single(c => c.No.Equals(no));
        }
        public void Ship(ShipmentOrder shipmentOrder)
        {
            if (shipmentOrder.Status == ShipmentOrderStatus.Paid && shipmentOrder.Items.All(item => item.Commodity.ExternalShipperId.Equals("310"))
                && wangCangStoreService.CreateShipmentOrderr(shipmentOrder))
            {
                shipmentOrder.Status = ShipmentOrderStatus.Packeging;
                base.Update(shipmentOrder);
            }
            else
            {
                shipmentOrder.Status = ShipmentOrderStatus.Shipping;
                base.Update(shipmentOrder);
                if (shipmentOrder.Items.All(item => item.Commodity.ExternalShipperId.Equals("310") && wangCangStoreService.Ship(shipmentOrder)))
                {
                    shipmentOrder.Status = ShipmentOrderStatus.Shipping;
                    base.Update(shipmentOrder);
                }
            }
        }
        public void Ship(string no)
        {
            ShipmentOrder shipmentOrder = GetByNo(no);
            this.Ship(shipmentOrder);
        }

        public void Determine(ShipmentOrder shipmentOrder)
        {
            shipmentOrder.Status = ShipmentOrderStatus.Determining;
            base.Update(shipmentOrder);
        }

        public List<ShipmentOrder> FindByStatus(ShipmentOrderStatus status)
        {
            return base.Repository.Query().Where(c => c.Status == status).ToList();
        }

        public ShipmentOrder GetByLogisticsCode(string logisticsOrderCode)
        {
            return base.Repository.Query().SingleOrDefault(c => c.LogisticsOrderNo == logisticsOrderCode);
        }


        public IList<ShipmentOrder> GetByConsigner(string consigner)
        {

            return base.Repository.FindAll(Restrictions.Eq("ExternalShipperId", consigner), 
                Restrictions.Ge("Status", ShipmentOrderStatus.Paid),
                Restrictions.Lt("Status", ShipmentOrderStatus.Shipped)).OrderByDescending(model => model.CreatedTime).ToList();
        }
        public IDataObjectPagedSet<ShipmentOrder> GetByConsigner(string consigner, int size, int index)
        {

            return base.Repository.FindAll(size, index, null, Restrictions.Eq("ExternalShipperId", consigner),
                Restrictions.Ge("Status", ShipmentOrderStatus.Paid),
                Restrictions.Lt("Status", ShipmentOrderStatus.Shipped));
        }


        public IList<ShipmentOrder> GetByShipperId(int shipperId)
        {
            return ShipmentOrderRepository.FindUnShipmentOrderByShipper(shipperId);
        }

        public IList<ShipmentOrder> GetShippedOrderByConsigner(string consigner)
        {
            return base.Repository.FindAll(Restrictions.Eq("ExternalShipperId", consigner),
                Restrictions.Ge("Status", ShipmentOrderStatus.Shipped),
                Restrictions.Lt("Status", ShipmentOrderStatus.Received)).OrderByDescending(model => model.CreatedTime).ToList();
              
        }

        public IList<ShipmentOrder> GetShippedOrderByShipperId(int shipperId)
        {
            return ShipmentOrderRepository.FindByShipper(shipperId);

        }



    }
}

